<script setup>
import {onMounted, ref, watch} from "vue";
import $axios from "../../util/request.js";
import {ElMessage} from "element-plus";

const props = defineProps({
  // 表格数据
  data: {
    type: Array,
    default: () => []
  },
  // 接口请求地址
  url: {
    type: String,
    default: ''
  },
  // 使用POST请求方式，默认使用GET方式
  post: {
    type: Boolean,
    default: false
  },
  // 接口请求参数
  params: {
    type: Object,
    default: () => {
      return {};
    }
  },
  // 加载中状态
  loading: {
    type: Boolean,
    default: false
  },
  // 是否多选表格
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否分页表格,默认分页
  pagination: {
    type: Boolean,
    default: true
  },
  // 页大小
  pageSizes: {
    type: Array,
    default: () => [5, 10, 20, 50, 40, 100]
  },
});

const tableLoading = ref(props.loading);
// 表格数据
const tableData = ref([]);
// 分页参数
const pageParams = ref({
  currentPage: 1,
  pageSize: props.pageSizes[0],
  total: 0
});
// 多选表格选中的数据
const multipleSelection = ref([]);
/**
 * 监听数据变化
 */
watch(() => props.data, async () => {
  // 重新加载表格数据
  await getTableData();
}, {deep: true});
onMounted(async () => {
  await getTableData()
});

/**
 * 加载表格数据
 */
const getTableData = async () => {
  // 重置数据
  tableData.value = [];
  multipleSelection.value = [];
  tableLoading.value = true;
  if (props.url) {
    const request = {
      ...props.params,
      pageNum: pageParams.value.currentPage,
      pageSize: pageParams.value.pageSize
    };
    // todo 去掉值是空的参数（这个可以根据实际情况决定）
    for (let key in request) {
      if (request[key] === '' || request[key] === null) {
        delete request[key];
      }
    }
    console.log('请求参数：', request)
    // 请求接口
    const config = {
      method: props.post ? 'post' : 'get',
      url: props.url,
    };
    if (props.post) {
      config.data = request;
    } else {
      config.params = request;
    }
    await $axios(config).then((res) => {
      console.log('响应数据：', res)
      if (res.code !== 200) {
        ElMessage.error('表格数据加载失败！');
        return;
      }
      if (res.data) {
        tableData.value = res.data.record;
        pageParams.value.total = res.data.total;
      } else {
        tableData.value = [];
        pageParams.value.total = 0;
      }
    }).catch((error) => {
      console.log(error);
    });
  } else {
    tableData.value = props.data;
  }
  tableLoading.value = false;
};
/**
 * 处理分页组件的页码变化
 */
const handlePageChange = async (number, type) => {
  if (type === 'size-change') {
    pageParams.value.pageSize = number;
  } else {
    pageParams.value.currentPage = number;
  }
  // 重新加载表格数据
  await getTableData();
};
/**
 * 触发事件
 */
const emits = defineEmits(['cellDbClick', 'currentChange', 'rowClick']);
const handleEmits = (type, data) => {
  console.log(type, data)
  emits(type, data);
};
/**
 * 对外暴露方法
 */
defineExpose({
  // 重新加载表格数据
  loadTable: async () => {
    await getTableData();
  },
  // 获取表格数据
  getTableData: () => {
    return tableData.value;
  },
  // 获取表格多选选中的数据
  getMultipleSelection: () => {
    return multipleSelection.value;
  }
});
</script>

<template>
  <div class="v-table-container">
    <!--  表格区域  -->
    <el-table ref="table" :data="tableData" style="width: 100%;"
              v-loading="tableLoading" stripe border highlight-current-row v-bind="$attrs"
              @cell-dblclick="(row, column, cell, event) => handleEmits('cellDbClick', {row, column, cell, event})"
              @row-click="(row, column, event) => handleEmits('rowClick', {row, column, event})"
              @current-change="(row, oldRow) => handleEmits('currentChange', {row, oldRow})"
              @select="(selection) => multipleSelection = selection"
              @select-all="(selection) => multipleSelection = selection">
      <el-table-column v-if="multiple" width="50" type="selection"/>
      <slot name="default"></slot>
    </el-table>
    <!--  分页区域  -->
    <div v-if="pagination" class="v-table-pagination">
      <el-pagination :current-page="pageParams.currentPage"
                     :page-size="pageParams.pageSize" :total="pageParams.total" :page-sizes="pageSizes"
                     background size="small" layout="total, sizes, prev, pager, next, jumper"
                     @size-change="(number) => handlePageChange(number, 'size-change')"
                     @current-change="(number) => handlePageChange(number, 'current-change')"
                     v-bind="$attrs"/>
    </div>
  </div>
</template>

<style scoped>
.v-table-container {
  width: 100%;
  height: 100%;
  margin: 10px 0;
}

.v-table-pagination {
  margin-top: 10px;
}

:deep(.el-input__wrapper), :deep(.el-textarea__inner), :deep(.el-select__wrapper) {
  border-radius: 0;
}
</style>